﻿#include "FITKAbaqusAdaptorConstraint.h"
#include "InpKeyLineSpliter.h"
#include "FITKAbaqusINPReader.h"
#include "FITKAbaqusINPWriter.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaConstraintCoupling.h" 
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaConstraintTie.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaConstraintRigidBody.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaConstraintManager.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaAssembly.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaRefPoint.h"
#include "FITK_Component/FITKAbaqusData/FITKAbaqusPart.h"
#include "FITK_Component/FITKAbaqusData/FITKDataCase.h"
#include "FITK_Interface/FITKInterfacePhysics/FITKBoundaryLocation.h"
#include "FITK_Interface/FITKInterfaceModel/FITKComponentManager.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaTransform.h"
#include <QTextStream>
#include <QList>
#include <QDebug>
//命名空间
namespace IO
{
    QString FITKAbaqusAdaptorConstraint::getAdaptorClass()
    {
        return "IO::FITKAbaqusAdaptorConstraint";
    }

    bool FITKAbaqusAdaptorConstraint::adaptR()
    {
        //读取
        Interface::FITKAbaAbstractConstraint* constraint = dynamic_cast<Interface::FITKAbaAbstractConstraint*>(_dataObj);
        if (!constraint || !_reader || !_caseData)return false;
        bool readOK = false;
        //获取类型
        Interface::FITKAbaAbstractConstraint::FITKAbaConstraintType type = constraint->getConstraintType();
        if (type == Interface::FITKAbaAbstractConstraint::FITKAbaConstraintType::Coupling)
            readOK = this->constraintCouplingR();
        else if (type == Interface::FITKAbaAbstractConstraint::FITKAbaConstraintType::Tie)
            readOK = this->constraintTieR();
        else if (type == Interface::FITKAbaAbstractConstraint::FITKAbaConstraintType::RigidBody)
            readOK = this->constraintRigidBodyR();
        return readOK;
    }
    bool FITKAbaqusAdaptorConstraint::adaptW()
    {
        //写出
        Interface::FITKAbaAbstractConstraint* constraint = dynamic_cast<Interface::FITKAbaAbstractConstraint*>(_dataObj);
        if (!constraint || !_writer || !_caseData)return false;
        bool writerOK = false;
        if (!this->writeSurface())return false;
        //获取类型
        Interface::FITKAbaAbstractConstraint::FITKAbaConstraintType type = constraint->getConstraintType();
        if (type == Interface::FITKAbaAbstractConstraint::FITKAbaConstraintType::Coupling)
            writerOK = this->constraintCouplingW();
        else if (type == Interface::FITKAbaAbstractConstraint::FITKAbaConstraintType::Tie)
            writerOK = this->constraintTieW();
        else if (type == Interface::FITKAbaAbstractConstraint::FITKAbaConstraintType::RigidBody)
            writerOK = this->constraintRigidBodyW();
        return writerOK;
    }

    void FITKAbaqusAdaptorConstraint::setCaseData(AbaqusData::FITKDataCase* caseData)
    {
        _caseData = caseData;
        _tool.setCaseData(_caseData);
        //获取装配
        auto assembly = _caseData->getAssembly();
        if (!assembly)return;
        _transformManager = assembly->getTransformManager();
    }

    bool FITKAbaqusAdaptorConstraint::constraintCouplingR()
    {
        Interface::FITKAbaConstraintCoupling* constraint = dynamic_cast<Interface::FITKAbaConstraintCoupling*>(_dataObj);
        if (!constraint)return false;       
        //回退一行，处理关键字信息
        _reader->backLine();
        QString line = _reader->readLine();
        //处理数据
        InpKeyLineSpliter s(line, _reader);
        QString refNode = s["ref node"];
        QString surface = s["surface"];
        constraint->setDataObjectName(s["constraint name"]);
        //影响半径方式判定和获取影响半径值
        if (s.hasKey("influence radius"))
        {
            constraint->setInfluenceRadius(Interface::FITKAbaConstraintCoupling::InfluenceRadius::Specify);
            constraint->setInfluenceRadiusValue(s["influence radius"].toDouble());
        }
        //获取参考点
        Interface::FITKBoundaryLocation* refLoc = constraint->getFirstLocation();
        int setModelID = -1;
        int setID = _tool.getSetIDByName(refNode, Interface::FITKModelEnum::FITKModelSetType::FMSNode, setModelID);
        //参考点
        if (_caseData->getAssembly())
            _caseData->getAssembly()->getRefPointBySet(setID, setModelID);
        if (setID == -1)return false;
        refLoc->setModel(setModelID);
        refLoc->setComponent(setID);
        //获取表面	
        Interface::FITKBoundaryLocation* location2 = constraint->getSecondLocation();
        int surfID = _tool.getSurfIDByName(surface, -1, setModelID);
        if (surfID == -1)return false;
        location2->setModel(setModelID);
        location2->setComponent(surfID);
        //获取局部坐标系
        
        int csysId = 0;
        if (_transformManager && s.hasKey("orientation"))
        {
            QString orientation = QString("Ori_%1").arg(s["orientation"]);
            auto transform = _transformManager->getDataByName(orientation);
            if (transform)csysId = transform->getDataObjectID();
        }
        constraint->setCsysId(csysId);
        //它必须与Kinematic或 DISTRIBUTING选项结合使用
        line = _reader->readLine();
        s.reset(line);
        //获取Coupling类型
        if (s.getHeader().startsWith("Kinematic"))
            constraint->setCouplingType(Interface::FITKAbaConstraintCoupling::CouplingType::Kinematic);
        else if (s.getHeader().startsWith("Distributing"))
            if (s["coupling"].toUpper() == "STRUCTURAL")
                constraint->setCouplingType(Interface::FITKAbaConstraintCoupling::CouplingType::StructualDistributing);
            else
                constraint->setCouplingType(Interface::FITKAbaConstraintCoupling::CouplingType::ContinuumDistributing);
        else//没有类型就是错误
            return false;
        //获取权重方法
        QString type = s["weighting method"];
        if (type.toUpper() == "UNIFORM")
            constraint->setWeightingMethod(Interface::FITKAbaConstraintCoupling::WeightingMethod::Uniform);
        else if (type.toUpper() == "LINEAR")
            constraint->setWeightingMethod(Interface::FITKAbaConstraintCoupling::WeightingMethod::Linear);
        else if (type.toUpper() == "QUADRATIC")
            constraint->setWeightingMethod(Interface::FITKAbaConstraintCoupling::WeightingMethod::Quadratic);
        else if (type.toUpper() == "CUBIC")
            constraint->setWeightingMethod(Interface::FITKAbaConstraintCoupling::WeightingMethod::Cubic);
        //初始化6个U状态
        constraint->setU1(false);
        constraint->setU2(false);
        constraint->setU3(false);
        constraint->setUR1(false);
        constraint->setUR2(false);
        constraint->setUR3(false);
        //设置6个U状态
        bool isAll = true;
        while (!_reader->atEnd())
        {
            line = _reader->readLine();
            if (line.startsWith("*"))
                break;
            isAll = false;
            QStringList str = line.split(',');
            if (str.size() < 2)return false;
            bool ok = false;
            int uType = str.at(0).toInt(&ok);
            if (!ok)return false;
            //设置U状态
            switch (uType)
            {
            case 1:constraint->setU1(true); break;
            case 2:constraint->setU2(true); break;
            case 3:constraint->setU3(true); break;
            case 4:constraint->setUR1(true); break;
            case 5:constraint->setUR2(true); break;
            case 6:constraint->setUR3(true); break;
            }
        }
        //没有就证明设置全部
        if (isAll)
        {
            constraint->setU1(true);
            constraint->setU2(true);
            constraint->setU3(true);
            constraint->setUR1(true);
            constraint->setUR2(true);
            constraint->setUR3(true);
        }
        //获取是否进行了调整
        s.reset(line);
        if (s.getHeader().startsWith("Adjust"))
            constraint->setAdjustCentrolPoints(true);
        return true;
    }

    bool FITKAbaqusAdaptorConstraint::constraintTieR()
    {
        Interface::FITKAbaConstraintTie* constraint = dynamic_cast<Interface::FITKAbaConstraintTie*>(_dataObj);
        if (!constraint)return false;
        //回退一行，处理关键字信息
        _reader->backLine();
        QString line = _reader->readLine();
        //处理数据
        InpKeyLineSpliter s(line, _reader);
        constraint->setDataObjectName(s["name"]);
        //获取离散方法
        QString type = s["type"].toUpper();
        if (type == "NODE TO SURFACE")
            constraint->setDiscretizationMethod(Interface::FITKAbaConstraintTie::DiscretizationMethod::NodeToSurface);
        else if (type == "SURFACE TO SURFACE")
            constraint->setDiscretizationMethod(Interface::FITKAbaConstraintTie::DiscretizationMethod::SurfaceToSurface);
        //是否排除单元厚度
        if (s.hasKey("no thickness"))
            constraint->setExcludeShellThickness(true);
        //位置公差类型判定和获取指定距离
        if (s.hasKey("position tolerance"))
        {
            constraint->setPostionTol(Interface::FITKAbaConstraintTie::PositionTolerance::SpecifyDistance);
            constraint->setPositionDistance(s["position tolerance"].trimmed().toDouble());
        }
        //是否绑定转动自由度
        if (s["adjust"].toLower() == "no")
            constraint->setAdjustSlave(false);
        //是否调整从表面初始位置
        if (s.hasKey("no rotation"))
            constraint->setTieRotationDofs(false);
        //约束比类型判定和获取指定值
        if (s.hasKey("constraint ratio"))
        {
            constraint->setConstraintRatio(Interface::FITKAbaConstraintTie::ConstraintRatio::SpecifyValue);
            constraint->setConstraintRatioValue(s["constraint ratio"].trimmed().toDouble());
        }
        line = _reader->readLine();
        //记录主表面
        Interface::FITKBoundaryLocation* location1 = constraint->getFirstLocation();
        //记录从表面
        Interface::FITKBoundaryLocation* location2 = constraint->getSecondLocation();
        QStringList surfNameList = line.split(',');
        if (surfNameList.size() < 2)return false;
        //获取从表面
        int instanceId = -1;
        int surfID = _tool.getSurfIDByName(surfNameList.at(0).trimmed(), -1, instanceId);
        if (surfID == -1)return false;
        location2->setModel(instanceId);
        location2->setComponent(surfID);
        //获取主表面
        surfID = _tool.getSurfIDByName(surfNameList.at(1).trimmed(), -1, instanceId);
        if (surfID == -1)return false;
        location1->setModel(instanceId);
        location1->setComponent(surfID);
        return true;
    }

    bool FITKAbaqusAdaptorConstraint::constraintRigidBodyR()
    {
        Interface::FITKAbaConstraintRigidBody* constraint = dynamic_cast<Interface::FITKAbaConstraintRigidBody*>(_dataObj);
        if (!constraint || !_reader)return false;
        Interface::FITKAbaConstraintManager* constraintManager = _caseData->getConstraintManager();
        if (!constraintManager)return false;
        //回退一行，处理关键字信息
        _reader->backLine();
        QString line = _reader->readLine();
        //处理数据
        InpKeyLineSpliter s(line, _reader);
        QString refNode = s["ref node"];
        QString elset = s["elset"];
        QString pinNset = s["pin nset"];
        QString tieNset = s["tie nset"];
        QString analyticalSurface = s["analytical surface"];
        //创建并设置名称
        QString name = constraintManager->checkName("RigidBody-1");
        constraint->setDataObjectName(name);
        //在分析开始时将点调整到质心
        if (s["position"].toUpper() == "CENTER OF MASS")
            constraint->setAdjustPoint(true);
        //将所选区域限制为等温的(只应用于耦合热-应力分析)
        if (s["isothermal"].toUpper() == "YES")
            constraint->setConstraintSelectedRegionToBeIsothermal(true);
        //获取参考点
        Interface::FITKBoundaryLocation* refLoc = constraint->getReferencePoint();
        int instanceId = -1;
        int setID = _tool.getSetIDByName(refNode, Interface::FITKModelEnum::FITKModelSetType::FMSNode, instanceId);
        if (setID == -1)return false;
        //参考点
        if (_caseData->getAssembly())
            _caseData->getAssembly()->getRefPointBySet(setID, instanceId);
        refLoc->setModel(instanceId);
        refLoc->setComponent(setID);
        //获取体
        if (!elset.isEmpty())
        {
            Interface::FITKBoundaryLocation* bodySet = constraint->getBody();
            setID = _tool.getSetIDByName(elset, Interface::FITKModelEnum::FITKModelSetType::FMSElem, instanceId);
            if (setID == -1)return false;
            bodySet->setModel(instanceId);
            bodySet->setComponent(setID);
        }
        //获取铰结(结点)
        if (!pinNset.isEmpty())
        {
            Interface::FITKBoundaryLocation* pinSet = constraint->getPin();
            setID = _tool.getSetIDByName(pinNset, Interface::FITKModelEnum::FITKModelSetType::FMSNode, instanceId);
            if (setID == -1)return false;
            pinSet->setModel(instanceId);
            pinSet->setComponent(setID);
        }
        //绑定(结点)
        if (!tieNset.isEmpty())
        {
            Interface::FITKBoundaryLocation* tieSet = constraint->getTie();
            setID = _tool.getSetIDByName(tieNset, Interface::FITKModelEnum::FITKModelSetType::FMSNode, instanceId);
            if (setID == -1)return false;
            tieSet->setModel(instanceId);
            tieSet->setComponent(setID);
        }
        //解析表面
        if (!analyticalSurface.isEmpty())
        {
            Interface::FITKBoundaryLocation* analyticalSurfaceData = constraint->getAnalyticalSurface();
            int surfID = _tool.getSurfIDByName(analyticalSurface, Interface::MeshSurfaceType::SurEle, instanceId);
            if (surfID == -1)return false;
            analyticalSurfaceData->setModel(instanceId);
            analyticalSurfaceData->setComponent(surfID);
        }
        _reader->readLine();
        return true;
    }

    bool FITKAbaqusAdaptorConstraint::constraintCouplingW()
    {
        Interface::FITKAbaConstraintCoupling* constraint = dynamic_cast<Interface::FITKAbaConstraintCoupling*>(_dataObj);
        if (!constraint || !_caseData || !_writer)return false;
        QTextStream* stream = _writer->getStream();
        //获取参考点名称
        Interface::FITKBoundaryLocation* location1 = constraint->getFirstLocation();
        //获取点集
        Interface::FITKModelSet* set = dynamic_cast<Interface::FITKModelSet*>(location1->getComponentObj());
        if (!set) return false;
        QString refName = set->getDataObjectName();
        refName = refName.contains(' ') ? QString("\"%1\"").arg(refName) : refName;
        if (location1->getModelObj() && location1->getModelID() != set->getAbsModelID() && location1->getModelObj()->getAbsModelType() == Interface::FITKModelEnum::AbsModelType::AssInstance)
        {
            QString name = location1->getModelObj()->getDataObjectName();
            name = name.contains(' ') ? QString("\"%1\"").arg(name) : name;
            refName = name + "." + refName;
        }
        //获取表面名称
        Interface::FITKBoundaryLocation* location2 = constraint->getSecondLocation();
        auto surf = location2->getComponentObj();
        if (!surf)return false;
        QString surfName;
        if (_surfaceName.isEmpty() || _surfaceName.at(0).isEmpty())
        {
            surfName = surf->getDataObjectName();
            surfName = surfName.contains(' ') ? QString("\"%1\"").arg(surfName) : surfName;
            if (location2->getModelObj() && location2->getModelID() != surf->getAbsModelID() && location2->getModelObj()->getAbsModelType() == Interface::FITKModelEnum::AbsModelType::AssInstance)
            {
                QString name = location2->getModelObj()->getDataObjectName();
                name = name.contains(' ') ? QString("\"%1\"").arg(name) : name;
                surfName = name + "." + surfName;
            }
        }
        else
            surfName = _surfaceName.at(0);
        //写出Coupling
        QString constraintName = constraint->getDataObjectName();
        constraintName = constraintName.contains(' ') ? QString("\"%1\"").arg(constraintName) : constraintName;
        QString lineOne = QString("*Coupling, constraint name=%1, ref node=%2, surface=%3").arg(constraintName).arg(refName).arg(surfName);
        if (constraint->getCsysId() != 0 && _transformManager)
        {
            auto transform = _transformManager->getDataByID(constraint->getCsysId());
            QString transName = transform->getDataObjectName();
            transName = transName.contains(' ') ? QString("\"%1\"").arg(transName) : transName;
            if (transform)lineOne += QString(", orientation=%1").arg(transName);
        }
        if (constraint->getInfluenceRadius() == Interface::FITKAbaConstraintCoupling::InfluenceRadius::Specify)
            lineOne += QString(", influence radius=%1").arg(_writer->double2String(constraint->getInfluenceRadiusValue(), 9, 0));
        *stream << lineOne << endl;
        //获取权重方法
        QString weightingStr;
        Interface::FITKAbaConstraintCoupling::WeightingMethod weightingmethod = constraint->getWeightingMethod();
        if (weightingmethod == Interface::FITKAbaConstraintCoupling::WeightingMethod::Uniform)
            weightingStr = ", weighting method=UNIFORM";
        else if (weightingmethod == Interface::FITKAbaConstraintCoupling::WeightingMethod::Linear)
            weightingStr = ", weighting method=LINEAR";
        else if (weightingmethod == Interface::FITKAbaConstraintCoupling::WeightingMethod::Quadratic)
            weightingStr = ", weighting method=QUADRATIC";
        else if (weightingmethod == Interface::FITKAbaConstraintCoupling::WeightingMethod::Cubic)
            weightingStr = ", weighting method=CUBIC";
        //写出Coupling类型
        Interface::FITKAbaConstraintCoupling::CouplingType typeCoupLing = constraint->couplingType();
        if (typeCoupLing == Interface::FITKAbaConstraintCoupling::CouplingType::Kinematic)
            lineOne = "*Kinematic";
        else if (typeCoupLing == Interface::FITKAbaConstraintCoupling::CouplingType::StructualDistributing)
            lineOne = "*Distributing" + weightingStr + ", coupling=STRUCTURAL";
        else if (typeCoupLing == Interface::FITKAbaConstraintCoupling::CouplingType::ContinuumDistributing)
            lineOne = "*Distributing" + weightingStr;
        *stream << lineOne << endl;
        if (!(constraint->getU1() && constraint->getU2() && constraint->getU3() && constraint->getUR1() && constraint->getUR2() && constraint->getUR3()))
        {
            if (constraint->getU1())
                *stream << "1, 1" << endl;
            if (constraint->getU2())
                *stream << "2, 2" << endl;
            if (constraint->getU3())
                *stream << "3, 3" << endl;
            if (constraint->getUR1())
                *stream << "4, 4" << endl;
            if (constraint->getUR2())
                *stream << "5, 5" << endl;
            if (constraint->getUR3())
                *stream << "6, 6" << endl;
        }
        if (constraint->getAdjustCentrolPoints())
            *stream << QString("*Adjust, node set=%1, surface=%2").arg(refName).arg(surfName) << endl;
        return true;
    }

    bool FITKAbaqusAdaptorConstraint::constraintTieW()
    {
        Interface::FITKAbaConstraintTie* constraint = dynamic_cast<Interface::FITKAbaConstraintTie*>(_dataObj);
        if (!constraint || !_caseData || !_writer)return false;
        QTextStream* stream = _writer->getStream();
        //写出Tie
        QString constraintName = constraint->getDataObjectName();
        constraintName = constraintName.contains(' ') ? QString("\"%1\"").arg(constraintName) : constraintName;
        QString lineOne = QString("*Tie, name=%1").arg(constraintName);
        //写出是否调整
        if (constraint->getAdjustSlave())
            lineOne += ", adjust=yes";
        else
            lineOne += ", adjust=no";
        //写出位置容差
        if (constraint->getPostionTolerance() == Interface::FITKAbaConstraintTie::PositionTolerance::SpecifyDistance)
            lineOne += QString(", position tolerance=%1").arg(_writer->double2String(constraint->getPositionDistance(), 9, 0));
        //写出不绑定旋转自由度
        if (!constraint->getTieRotationDofs())
            lineOne += ", no rotation";
        //写出约束比
        if (constraint->getConstraintRatio() == Interface::FITKAbaConstraintTie::ConstraintRatio::SpecifyValue)
            lineOne += QString(", constraint ratio=%1").arg(_writer->double2String(constraint->getConstraintRatioValue(), 9, 0));
        //写出离散方法
        if (constraint->getDiscretizationMethod() == Interface::FITKAbaConstraintTie::DiscretizationMethod::NodeToSurface)
            lineOne += QString(", type=NODE TO SURFACE");
        else if (constraint->getDiscretizationMethod() == Interface::FITKAbaConstraintTie::DiscretizationMethod::SurfaceToSurface)
            lineOne += QString(", type=SURFACE TO SURFACE");
        //写出排除壳厚度
        if (constraint->getExcludeShellThickness())
            lineOne += ", no thickness";
        *stream << lineOne << endl;
        //获取从表面
        Interface::FITKBoundaryLocation* location2 = constraint->getSecondLocation();
        auto surf = location2->getComponentObj();
        if (!surf)return false;
        QString surfName1;
        if (_surfaceName.isEmpty() || _surfaceName.at(1).isEmpty())
        {
            surfName1 = surf->getDataObjectName();
            surfName1 = surfName1.contains(' ') ? QString("\"%1\"").arg(surfName1) : surfName1;
            if (location2->getModelObj() && location2->getModelID() != surf->getAbsModelID() && location2->getModelObj()->getAbsModelType() == Interface::FITKModelEnum::AbsModelType::AssInstance)
            {
                QString name = location2->getModelObj()->getDataObjectName();
                name = name.contains(' ') ? QString("\"%1\"").arg(name) : name;
                surfName1 = name + "." + surfName1;
            }
        }
        else
            surfName1 = _surfaceName.at(1);
        //获取主表面
        Interface::FITKBoundaryLocation* location1 = constraint->getFirstLocation();
        surf = location1->getComponentObj();
        if (!surf)return false;
        QString surfName2;
        if (_surfaceName.size() < 2 || _surfaceName.at(0).isEmpty())
        {
            surfName2 = surf->getDataObjectName();
            surfName2 = surfName2.contains(' ') ? QString("\"%1\"").arg(surfName2) : surfName2;
            if (location1->getModelObj() && location1->getModelID() != surf->getAbsModelID() && location1->getModelObj()->getAbsModelType() == Interface::FITKModelEnum::AbsModelType::AssInstance)
            {
                QString name = location1->getModelObj()->getDataObjectName();
                name = name.contains(' ') ? QString("\"%1\"").arg(name) : name;
                surfName2 = name + "." + surfName2;
            }
        }
        else
            surfName2 = _surfaceName.at(0);
        *stream << QString("%1, %2").arg(surfName1).arg(surfName2) << endl;
        return true;
    }

    bool FITKAbaqusAdaptorConstraint::constraintRigidBodyW()
    {
        Interface::FITKAbaConstraintRigidBody* constraint = dynamic_cast<Interface::FITKAbaConstraintRigidBody*>(_dataObj);
        if (!constraint || !_writer || !_caseData)return false;
        QTextStream* stream = _writer->getStream();
        //获取参考点
        Interface::FITKBoundaryLocation* refLoc = constraint->getReferencePoint();
        if (!refLoc) return false;
        //获取点集
        Interface::FITKModelSet* set = dynamic_cast<Interface::FITKModelSet*>(refLoc->getComponentObj());
        if (!set)
        {
            Interface::FITKAbaRefPoint* refNode = dynamic_cast<Interface::FITKAbaRefPoint*>(refLoc->getComponentObj());
            if (!refNode)return false;
            set = refNode->getSet();
            if (!set)return false;
        }
        //获取参考点名称
        QString refName = set->getDataObjectName();
        refName = refName.contains(' ') ? QString("\"%1\"").arg(refName) : refName;
        if (refLoc->getModelObj() && refLoc->getModelID() != set->getAbsModelID() && refLoc->getModelObj()->getAbsModelType() == Interface::FITKModelEnum::AbsModelType::AssInstance)
        {
            QString name = refLoc->getModelObj()->getDataObjectName();
            name = name.contains(' ') ? QString("\"%1\"").arg(name) : name;
            refName = name + "." + refName;
        }
        //写出Tie
        QString lineOne = QString("*Rigid Body, ref node=%1").arg(refName);
        //获取体
        Interface::FITKBoundaryLocation* bodySet = constraint->getBody();
        if (!bodySet) return false;
        //获取单元集合
        set = dynamic_cast<Interface::FITKModelSet*>(bodySet->getComponentObj());
        if (set)
        {
            //获取体名称
            QString bodyName = set->getDataObjectName();
            bodyName = bodyName.contains(' ') ? QString("\"%1\"").arg(bodyName) : bodyName;
            if (bodySet->getModelObj() && bodySet->getModelID() != set->getAbsModelID() && bodySet->getModelObj()->getAbsModelType() == Interface::FITKModelEnum::AbsModelType::AssInstance)
            {
                QString name = bodySet->getModelObj()->getDataObjectName();
                name = name.contains(' ') ? QString("\"%1\"").arg(name) : name;
                bodyName = name + "." + bodyName;
            }
            lineOne += QString(", elset=%1").arg(bodyName);
        }
        //获取铰结(结点)
        Interface::FITKBoundaryLocation* pinSet = constraint->getPin();
        if (!pinSet) return false;
        //获取节点集合
        set = dynamic_cast<Interface::FITKModelSet*>(pinSet->getComponentObj());
        if (set)
        {
            //获取体名称
            QString pinName = set->getDataObjectName();
            pinName = pinName.contains(' ') ? QString("\"%1\"").arg(pinName) : pinName;
            if (pinSet->getModelObj() && pinSet->getModelID() != set->getAbsModelID() && pinSet->getModelObj()->getAbsModelType() == Interface::FITKModelEnum::AbsModelType::AssInstance)
            {
                QString name = pinSet->getModelObj()->getDataObjectName();
                name = name.contains(' ') ? QString("\"%1\"").arg(name) : name;
                pinName = name + "." + pinName;
            }
            lineOne += QString(", pin nset=%1").arg(pinName);
        }
        //绑定(结点)
        Interface::FITKBoundaryLocation* tieSet = constraint->getTie();
        if (!tieSet) return false;
        //获取节点集合
        set = dynamic_cast<Interface::FITKModelSet*>(tieSet->getComponentObj());
        if (set)
        {
            //获取体名称
            QString tieName = set->getDataObjectName();
            tieName = tieName.contains(' ') ? QString("\"%1\"").arg(tieName) : tieName;
            if (tieSet->getModelObj() && tieSet->getModelID() != set->getAbsModelID() && tieSet->getModelObj()->getAbsModelType() == Interface::FITKModelEnum::AbsModelType::AssInstance)
            {
                QString name = tieSet->getModelObj()->getDataObjectName();
                name = name.contains(' ') ? QString("\"%1\"").arg(name) : name;
                tieName = name + "." + tieName;
            }
            lineOne += QString(", tie nset=%1").arg(tieName);
        }
        //解析表面
        Interface::FITKBoundaryLocation* analyticalSurfaceData = constraint->getAnalyticalSurface();
        if (!analyticalSurfaceData) return false;
        auto surf = analyticalSurfaceData->getComponentObj();
        if (surf)
        {
            QString surfName = surf->getDataObjectName();
            surfName = surfName.contains(' ') ? QString("\"%1\"").arg(surfName) : surfName;
            if (analyticalSurfaceData->getModelObj() && analyticalSurfaceData->getModelID() != surf->getAbsModelID() && analyticalSurfaceData->getModelObj()->getAbsModelType() == Interface::FITKModelEnum::AbsModelType::AssInstance)
            {
                QString name = analyticalSurfaceData->getModelObj()->getDataObjectName();
                name = name.contains(' ') ? QString("\"%1\"").arg(name) : name;
                surfName = name + "." + surfName;
            }
            lineOne += QString(", analytical surface").arg(surfName);
        }
        //在分析开始时将点调整到质心
        if (constraint->getAdjustPoint())
            lineOne += QString(", position=CENTER OF MASS");
        //将所选区域限制为等温的(只应用于耦合热-应力分析)
        if (constraint->getConstraintSelectedRegionToBeIsothermal())
            lineOne += QString(", isothermal=YES");
        *stream << lineOne << endl;
        return true;
    }

    bool FITKAbaqusAdaptorConstraint::writeSurface()
    {
        Interface::FITKAbaAbstractConstraint* constraint = dynamic_cast<Interface::FITKAbaAbstractConstraint*>(_dataObj);
        if (!constraint || !_writer || !_caseData)return false;
        //获取类型
        Interface::FITKAbaAbstractConstraint::FITKAbaConstraintType type = constraint->getConstraintType();
        if (type == Interface::FITKAbaAbstractConstraint::FITKAbaConstraintType::Coupling)
        {
            Interface::FITKAbaConstraintCoupling* constraintData = dynamic_cast<Interface::FITKAbaConstraintCoupling*>(constraint);
            if (!constraintData)return false;
            //获取表面名称
            Interface::FITKBoundaryLocation* location2 = constraint->getSecondLocation();
            Interface::FITKAbstractModelComponent* model = location2->getComponentObj();
            if (!model)return false;
            Interface::FITKMeshSurface* surface = dynamic_cast<Interface::FITKMeshSurface*>(model);
            if (!surface)
                return this->writeSurfaceBySetData(dynamic_cast<Interface::FITKModelSet*>(model));
            else
                _surfaceName.append("");
        }
        else if (type == Interface::FITKAbaAbstractConstraint::FITKAbaConstraintType::Tie)
        {
            Interface::FITKAbaConstraintTie* constraintData = dynamic_cast<Interface::FITKAbaConstraintTie*>(constraint);
            if (!constraintData)return false;
            //获取表面名称
            Interface::FITKBoundaryLocation* location1 = constraint->getFirstLocation();
            Interface::FITKAbstractModelComponent* model = location1->getComponentObj();
            if (!model)return false;
            Interface::FITKMeshSurface* surface = dynamic_cast<Interface::FITKMeshSurface*>(model);
            if (!surface)
            {
                if (!this->writeSurfaceBySetData(dynamic_cast<Interface::FITKModelSet*>(model)))return false;
            }
            else
                _surfaceName.append("");
            //获取表面名称
            Interface::FITKBoundaryLocation* location2 = constraint->getSecondLocation();
            model = location2->getComponentObj();
            if (!model)return false;
            surface = dynamic_cast<Interface::FITKMeshSurface*>(model);
            if (!surface)
            {
                if (!this->writeSurfaceBySetData(dynamic_cast<Interface::FITKModelSet*>(model)))return false;
            }
            else
                _surfaceName.append("");
        }
        else if (type == Interface::FITKAbaAbstractConstraint::FITKAbaConstraintType::RigidBody)
        {
            Interface::FITKAbaConstraintRigidBody* constraintData = dynamic_cast<Interface::FITKAbaConstraintRigidBody*>(constraint);
            if (!constraintData)return false;
        }
        return true;
    }

    bool FITKAbaqusAdaptorConstraint::writeSurfaceBySetData(Interface::FITKModelSet* set)
    {
        if (!set || !_writer)return false;
        QTextStream* stream = _writer->getStream();
        //获取名称
        QString setName = set->getDataObjectName();
        QString name = QString("%1_CNS_").arg(setName);
        setName = setName.contains(' ') ? QString("\"%1\"").arg(setName) : setName;
        name = name.contains(' ') ? QString("\"%1\"").arg(name) : name;
        //获取类型
        Interface::FITKModelEnum::FITKModelSetType type;
        if (set->isCombination())
        {
            type = set->getDataByIndex(0)->getModelSetType();
        }
        else
            type = set->getModelSetType();
        //通过类型写出surface
        if (type == Interface::FITKModelEnum::FITKModelSetType::FMSNode)
        {
            *stream << QString("*Surface, type=NODE, name=%1, internal").arg(name) << endl;
            *stream << QString("%1, 1.").arg(setName) << endl;
        }
        else if (type == Interface::FITKModelEnum::FITKModelSetType::FMSElem)
        {

        }
        _surfaceName.append(name);
        return true;
    }
}
